Skip to main content

Firewall Setup

The default Armbian OS does not ship with a firewall. So we need to set up our own firewall. For Ubuntu there are multiple options like UFW and iptables.

But iptables are more preferred because they are much more compatible with the docker.

Step 1: Install iptables

  1. Start by updating your package repositories to ensure you get the latest version of iptables:
sudo apt update
  1. Now, you can install iptables and iptables-persistent.Install the iptables-persistent package to ensure that your rules are automatically loaded at boot
sudo apt install iptables
sudo apt install iptables-persistent
  1. Verify the Installation. This command will display the installed version of iptables, confirming that it’s ready for use.
sudo iptables --version

Step 2: Setting up firewall rules

One approach is that you start by blocking everything on your IPV 4 and IPV 6 tables. These file are all rules can be added to the separate files, namely rules.V4 and rules.V6.

sudo nano /etc/iptables/rules.v4

An example rules.v4 files will look like this

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -i tailscale0 -j ACCEPT
-A INPUT -s 123.123.123.123 -p tcp -m tcp --dport 9090 -j ACCEPT
-A INPUT -s 123.123.123.123 -p tcp -m tcp --dport 8888 -j ACCEPT
-A INPUT -s 195.165.165.0/24 -p tcp --dport 9090 -j ACCEPT
-A INPUT -s 195.165.165.0/24 -p tcp --dport 8888 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

Default Policies

  • INPUT: DROP → All incoming traffic is blocked unless explicitly allowed.
  • FORWARD: DROP → No packet forwarding between interfaces.
  • OUTPUT: ACCEPT → All outgoing traffic is allowed.

Allowed Incoming Traffic

RuleProtocolPort(s)SourceDescription
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPTAnyAnyEstablished connectionsAllows replies to outgoing connections.
-A INPUT -i lo -j ACCEPTAnyAnyLocalhostPermits loopback traffic.
-A INPUT -p icmp -j ACCEPTICMPN/AAnyAllows ping and ICMP messages.
-A INPUT -p tcp --dport 22 -j ACCEPTTCP22AnySSH access. (you can also allow specific IP for better protection see example below)
-A INPUT -p tcp --dport 80 -j ACCEPTTCP80AnyHTTP web traffic.
-A INPUT -p tcp --dport 443 -j ACCEPTTCP443AnyHTTPS web traffic.
-A INPUT -i tailscale0 -j ACCEPTAnyAnytailscale0 interfaceAllows traffic from Tailscale VPN.
-A INPUT -s 123.123.123.123 -p tcp --dport 9090 -j ACCEPTTCP9090100.100.1.1Allows custom service from specific IP (tailscale).
-A INPUT -s 123.123.123.123 -p tcp --dport 8888 -j ACCEPTTCP8888100.100.1.1Allows custom service from specific IP (tailscale).
-A INPUT -s 195.165.165.0/24 -p tcp --dport 9090 -j ACCEPTTCP9090Local LAN (195.165.165.0/24)Allows service access from LAN.
-A INPUT -s 195.165.165.0/24 -p tcp --dport 8888 -j ACCEPTTCP8888Local LAN (195.165.165.0/24)Allows service access from LAN.

Rejected Traffic

  • -A INPUT -j REJECT --reject-with icmp-host-prohibited
    → Any traffic not matching the above rules is rejected with an ICMP "host prohibited" message.

Summary

  • Secure default: Blocks all inbound traffic unless explicitly allowed.
  • Access granted: SSH (22), HTTP (80), HTTPS (443), ICMP, Tailscale, and specific services (9090, 8888) from trusted sources.
  • LAN & specific IPs: Only trusted networks/IPs can access sensitive ports.
  • Output unrestricted: Outbound traffic is fully allowed.

IPV6 Firewall Rules

Internally running service mostly use IPV4 like (localhost / 127.0.0.1) so for this reason we dont need to cofigure IPV6 rules for them. So we only apply the rules for outbount / web facing ports and keep everything else blocked.

An example rules.v6 files will look like this

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Accept established/related connections
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Accept loopback
-A INPUT -i lo -j ACCEPT
# Accept ICMPv6
-A INPUT -p icmpv6 -j ACCEPT
# Allow SSH
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# Allow HTTP
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# Allow HTTPS
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# Default reject
-A INPUT -j REJECT --reject-with icmp6-port-unreachable
COMMIT

Step 3: Enabling the rules

To implement this rule, we can run the following command.

sudo su -c 'iptables-restore < /etc/iptables/rules.v4'
sudo su -c 'iptables-restore < /etc/iptables/rules.v6'